 /**
 * 逻辑、功能相关描述: <br>
 *
 * @author 付湘辉  <br>
 * 编写日期：2008-8-6  <br>
 */
package com.ce.pms.charge.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.ce.pms.base.service.impl.PmsBaseServiceImpl;
import com.ce.pms.charge.dao.IChargeItemDao;
import com.ce.pms.charge.dao.IPrePaySchDao;
import com.ce.pms.charge.model.ChargeItemDomain;
import com.ce.pms.charge.model.PrePayAccountDomain;
import com.ce.pms.charge.model.PrePaySchDomain;
import com.ce.pms.charge.model.SchDetail;
import com.ce.pms.charge.service.IPrePaySchService;
import com.ce.pms.charge.vo.PrePaySchSearchVO;
import com.ce.pms.charge.vo.PrePaySchVO;
import com.ce.pms.charge.vo.SchDetailVO;
import com.ce.pms.common.model.SysInfo;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.exception.BusinessException;
import com.ce.pms.house.model.FlatDomain;
import com.ce.pms.house.vo.FlatVO;
import com.ce.util.BeanUtil;
import com.ce.util.BlankUtil;
import com.sitechasia.webx.core.support.Page;

/**
 * 	名称: com.ce.pms.charge.service.impl.PrePaySchServiceImpl <br>
 *
 *
 * @author  付湘辉  <br>
 * Created on： 2008-8-6 <br>
 * @author <br>
 * update on： <br>
 * why: <br>
 */
public class PrePaySchServiceImpl extends PmsBaseServiceImpl implements
		IPrePaySchService {
	/**
	 * 收费项目及标准Dao
	 */
	private IChargeItemDao chargeItemDao;

	/**
	 * 预交方案管理Dao
	 */
	private IPrePaySchDao prePaySchDao;

	/**
	 * <p>功能描述: 添加一个预交方案。</p>
	 * <h3>业务规则：</h3>
	 * <ol>
	 * <li>新的方案名称不能与已有的名称相同。</li>
	 * <li>如果新方案被设为默认值，会将系统中已有的默认方案设为非默认的方案，如果有的话。</li>
	 * <li>在实现中,先增加一个方案,然后处理其下的明细,如果有明细的话。</li>
	 * </ol>
	 * <h3><i>程序规则</i>：</h3>
	 * <ol>
	 * <li>新增成功后,会将新产生的主键设置到传入的VO对象中。</li>
	 * </ol>
	 * @param prePaySchVO
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public PrePaySchVO addPrePaySch(PrePaySchVO prePaySchVO){
		try {
			super.checkParameterIsNull(prePaySchVO,"common:parameters_null_exception, ");
			if (this.checkIsExistPrePaySch(prePaySchVO.getSchemeName())) {
				throw new BusinessException("charge:charge_prepay_name_exist_exception",
											BusinessException.WARNING);
			}
			processDefaultRole(prePaySchVO);

			PrePaySchDomain prePaySchDo = assembleV2D(prePaySchVO);

			this.prePaySchDao.saveObject(prePaySchDo);
			prePaySchVO.setPrePaySchId(prePaySchDo.getPrePaySchId());

			Set<SchDetail> tempSet = assembleSchDetailSet(prePaySchVO);

			prePaySchDo.getSchDetails().clear();
			if (!BlankUtil.isBlank(tempSet)) {
				prePaySchDo.getSchDetails().addAll(tempSet);
			}

			return prePaySchVO;
		} catch (BusinessException be) {
			super.logger.warn(be.getMessage(), be);
			throw be;
		} catch (Exception e) {
			super.logger.fatal(e.getMessage(), e);
			throw new BusinessException("charge:charge_prepay_add_fail_exception",BusinessException.FAILURE);
		}
	}

	/**
	 * 功能描述: 得到所有预交方案列表 <br>
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-9-5  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public List<PrePaySchVO> getAllPrePaySchList(){

		List<PrePaySchDomain> doList = this.prePaySchDao.findAll();
		if (BlankUtil.isBlank(doList)) {
			return null;
		}
		List<PrePaySchVO> list = new ArrayList<PrePaySchVO>();
		for (PrePaySchDomain domain : doList) {
			list.add(this.assembleD2V(domain,false));
		}
		return list;
	}

	/**
	 * 功能描述: 检查非指定id的预交方案名称是否存在 <br>
	 * @param schName
	 * @return true：存在 false：不存在
	 *
	 * @exception com.ce.pms.exception.BusinessException <br>
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean checkIsExistPrePaySch(Long prePaySchId, String schName){
		super.checkParameterIsNull("common:parameters_null_exception, ",prePaySchId,schName==null?schName:schName.trim());
		return this.prePaySchDao.getPrePaySchByNoSetIdAndName(prePaySchId, schName)!=null;
	}

	/**
	 * 功能描述: 检查指定的预交方案名称是否存在 <br>
	 * @param schName
	 * @return true：存在 false：不存在
	 *
	 * @exception com.ce.pms.exception.BusinessException <br>
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean checkIsExistPrePaySch(String schName){
		super.checkParameterIsNull(schName==null?schName:schName.trim(), "common:parameters_null_exception, ");
		return this.prePaySchDao.getPrePaySchByName(schName.trim()) != null;
	}

	/**
	 * 功能描述: 根据id删除一个预交方案 <br>
	 * @param prePaySchId
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-7  <br>
	 * Edit author:  付湘辉<br>
	 * Edit on:  2008-11-28  <br>
	 * Why:  默认的方案不能删除   <br>
	 */
	public void deletePrePaySch(Long prePaySchId){
		try {
			super.checkParameterIsNull(prePaySchId,"common:parameters_null_exception,ID");
			PrePaySchDomain prePaySchDo = this.prePaySchDao.findById(prePaySchId);
			if (BlankUtil.isBlank(prePaySchDo)) {
				return;
			}
			// 2008-11-28 增加逻辑  默认的方案不能删除
			// 修改人 付湘辉
			if (PrePaySchDomain.IS_DEFAULT.equals(prePaySchDo.getIsDefault())) {
				throw new BusinessException("charge:charge_default_prepay_donot_delete_exception",
						BusinessException.WARNING);
			}
			//	2008-11-28 增加逻辑 
			if (SysrefcodeDO.CONSTANTS_ZERO < prePaySchDo.getPrePayAccountes().size()) {
				throw new BusinessException("charge:charge_prepay_has_using_exception",
											BusinessException.WARNING);
			}

			this.prePaySchDao.deleteObject(prePaySchDo);
		} catch (BusinessException be) {
			super.logger.fatal(be.getMessage(),be);
			throw be;
		} catch (Exception e) {
			super.logger.fatal(e.getMessage(),e);
			throw new BusinessException("charge:charge_prepay_delete_fail_exception",
					BusinessException.FAILURE);
		}
	}

	/**
	 * <p>功能描述: 修改一个预交方案。</p>
	 * <h3>业务规则：</h3>
	 * <ol>
	 * <li>新的方案名称不能除本预交方案之外的其它预交方案的名称相同。</li>
	 * <li>如果修改后方案被设为默认值，会将系统中已有的默认方案设为非默认的方案，如果有的话。</li>
	 * <li>在实现中,处理其下的明细,如果有明细的话。</li>
	 * </ol>
	 * @param prePaySchVO
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-7  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public PrePaySchVO editPrePaySch(PrePaySchVO prePaySchVO){
		try {
			super.checkParameterIsNull("common:parameters_null_exception, ",prePaySchVO,prePaySchVO.getPrePaySchId());
			if (this.checkIsExistPrePaySch(prePaySchVO.getPrePaySchId(),prePaySchVO.getSchemeName())) {
				throw new BusinessException("charge:charge_prepay_name_exist_exception",
											BusinessException.WARNING);
			}

			processDefaultRole(prePaySchVO);

			PrePaySchDomain prePaySchDo = assembleV2D(prePaySchVO);

			Set<SchDetail> tempSet = assembleSchDetailSet(prePaySchVO);
			prePaySchDo.getSchDetails().clear();
			if (!BlankUtil.isBlank(tempSet)) {
				prePaySchDo.getSchDetails().addAll(tempSet);
			}

			this.prePaySchDao.updateObject(prePaySchDo);

			return prePaySchVO;
		} catch (BusinessException be) {
			super.logger.warn(be.getMessage(), be);
			throw be;
		} catch (Exception e) {
			super.logger.fatal(e.getMessage(), e);
			throw new BusinessException("charge:charge_prepay_edit_fail_exception",BusinessException.FAILURE);
		}
	}

	/**
	 * 功能描述: 通过预交方案id查询预交方案VO <br>
	 * @param prePayId
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public PrePaySchVO findPrePaySchById(Long prePayId){
		super.checkParameterIsNull(prePayId, "common:parameters_null_exception, ");
		return this.assembleD2V(this.prePaySchDao.findById(prePayId),true);
	}

	/**
	 * 功能描述: 通过预交款子账户id查询预交方案VO <br>
	 * @param prePayAccountId
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public PrePaySchVO findPrePaySchByPrePayAccountId(Long prePayAccountId){
		super.checkParameterIsNull(prePayAccountId, "common:parameters_null_exception, ");

		return this.assembleD2V(this.prePaySchDao.findPrePaySchByPrePayAccountId(prePayAccountId),false);
	}

	/**
	 * 功能描述: 查询预交方案分页列表信息 <br>
	 * @param preSearch
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	@SuppressWarnings({"unchecked","unused"})
	public Page queryPrePaySchListByPage(PrePaySchSearchVO preSearch){
		super.checkParameterIsNull(preSearch, "common:parameters_null_exception, ");
		preSearch.checkRule();

		Page page = prePaySchDao.queryPagedPrePaySchs(preSearch);

		List<PrePaySchVO> list = null;

		if (SysrefcodeDO.CONSTANTS_ZERO < page.getTotalCount()) {
			List<PrePaySchDomain> doList = page.getResult();
			list = new ArrayList<PrePaySchVO>();
			for (PrePaySchDomain domain : doList) {
				list.add(assembleD2V(domain,true));
			}
			page.setResult(list);
		}

		return page;
	}

	/**
	 * @param chargeItemDao the chargeItemDao to set
	 */
	public void setChargeItemDao(IChargeItemDao chargeItemDao) {
		this.chargeItemDao = chargeItemDao;
	}

    /**
	 * @param prePaySchDao the prePaySchDao to set
	 */
	public void setPrePaySchDao(IPrePaySchDao prePaySchDao) {
		this.prePaySchDao = prePaySchDao;
	}

	/** 功能描述: 装配一个预交方案信息VO <br>
	 * @param prePaySchDomain
	 * @param withDetail 为true则处理方案明细信息
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private PrePaySchVO assembleD2V(PrePaySchDomain prePaySchDomain,boolean withDetail) {
		if (BlankUtil.isBlank(prePaySchDomain)) {
			return null;
		}
		PrePaySchVO prePaySchVo= new PrePaySchVO();

		BeanUtil.convertVoAsDo(prePaySchDomain, prePaySchVo);

		SysInfo info = prePaySchDomain.getSysInfo();
		prePaySchVo.setCreator(info.getCreator());
		prePaySchVo.setSysDate(info.getSysDate());
		prePaySchVo.setModifier(info.getModifier());
		prePaySchVo.setModifyDate(info.getModifyDate());

		if (withDetail) {
			dealSchDetail(prePaySchDomain, prePaySchVo);
		}

		return prePaySchVo;
	}

	/** 功能描述:  <br>
	 * @param prePaySchDomain
	 * @param prePaySchVo
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-9-5  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private void dealSchDetail(PrePaySchDomain prePaySchDomain, PrePaySchVO prePaySchVo) {
		Set<SchDetail> schDetails= prePaySchDomain.getSchDetails();
		if (!BlankUtil.isBlank(schDetails)) {
			List<SchDetailVO> tempList = new ArrayList<SchDetailVO>();
			Iterator<SchDetail> schIter= schDetails.iterator();
			while (schIter.hasNext()) {
				SchDetail schDetail = schIter.next();
				tempList.add(assembleD2V(schDetail));
			}
			Collections.sort(tempList);
			prePaySchVo.setSchDetails(tempList);
		}
	}

	/** 功能描述: 装配一个预交方案详细信息VO <br>
	 * @param schDetail
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private SchDetailVO assembleD2V(SchDetail schDetail) {
		SchDetailVO temp = new SchDetailVO();
		BeanUtil.convertVoAsDo(schDetail, temp);
		temp.setChargeItemId(schDetail.getChargeItem().getKeyword());
		temp.setChargeItemName(schDetail.getChargeItem().getItemName());
		temp.setPrePaySchId(schDetail.getPrePaySch().getPrePaySchId());
		temp.setPrePaySchName(schDetail.getPrePaySch().getSchemeName());
		return temp;
	}

	/** 功能描述:  <br>
	 * @param prePaySchVo
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-7  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private Set<SchDetail> assembleSchDetailSet(PrePaySchVO prePaySchVo) {
		Set<SchDetail> tempSet = null;
		List<SchDetailVO> tempList = prePaySchVo.getSchDetails();
		if (!BlankUtil.isBlank(tempList)) {
			tempSet = new HashSet<SchDetail>();
			for (SchDetailVO detailVO : tempList) {
				detailVO.setPrePaySchId(prePaySchVo.getPrePaySchId());
				tempSet.add(assembleV2D(detailVO));
			}
		}
		return tempSet;
	}

	/** 功能描述: 装配一个预交方案信息VO <br>
	 * @param prePaySchVo
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private PrePaySchDomain assembleV2D(PrePaySchVO prePaySchVo) {
		if (BlankUtil.isBlank(prePaySchVo)) {
			return null;
		}
		PrePaySchDomain prePaySchDomain = wangleDomainInstance(prePaySchVo);

		BeanUtil.convertVoAsDo(prePaySchVo, prePaySchDomain);

		return prePaySchDomain;
	}


	/** 功能描述: 装配一个预交方案详细信息VO <br>
	 * @param schDetail
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-6  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private SchDetail assembleV2D(SchDetailVO schDetailVo) {
		if (BlankUtil.isBlank(schDetailVo)) {
			return null;
		}
		SchDetail schDetail = null;
		if (BlankUtil.isBlank(schDetailVo.getSchDetailId())) {
			schDetail = new SchDetail();
		}else{
			schDetail = this.prePaySchDao.getSchDetailById(schDetailVo.getSchDetailId());
		}

		BeanUtil.convertVoAsDo(schDetailVo, schDetail);
		ChargeItemDomain chargeItemDo = this.chargeItemDao.findById(schDetailVo.getChargeItemId());
		schDetail.setChargeItem(chargeItemDo);
		PrePaySchDomain prePaySchDo = this.prePaySchDao.findById(schDetailVo.getPrePaySchId());
		schDetail.setPrePaySch(prePaySchDo);
		// 必填项检查
		schDetail.checkRequiredField();

		return schDetail;
	}

	/** 功能描述: 如果指定的预交方案是默认的，则将原来的默认方案改为非默认的 <br>
	 * @param prePaySchDo
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-7  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private void processDefaultRole(PrePaySchVO prePaySchVO) {
		// 得到默认的方案
		PrePaySchDomain acquiescent  = this.prePaySchDao.getDefaultPrePaySch();
		if (!BlankUtil.isBlank(acquiescent)) {
			if (acquiescent.getPrePaySchId().equals(prePaySchVO.getPrePaySchId())) {
				if (SysrefcodeDO.CONSTANTS_DIGITAL_ZERO.equals(prePaySchVO.getIsDefault())) {
					//不能将默认的方案设置为非默认方案
					throw new BusinessException("charge:charge_prepay_default_exception",BusinessException.WARNING);
				}
			}else {
				if (SysrefcodeDO.CONSTANTS_DIGITAL_ONE.equals(prePaySchVO.getIsDefault())) {
					acquiescent.setIsDefault(SysrefcodeDO.CONSTANTS_DIGITAL_ZERO);
					this.prePaySchDao.updateObject(acquiescent);
				}
			}
		}
	}

	/** 功能描述:  <br>
	 * @param prePaySchVo
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-5  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private PrePaySchDomain wangleDomainInstance(PrePaySchVO prePaySchVo) {
		PrePaySchDomain prePaySchDomain = null;
		SysInfo info = null;
		//不存在id则新实例化一个
		if (BlankUtil.isBlank(prePaySchVo.getPrePaySchId())) {
			prePaySchDomain= new PrePaySchDomain();
			info = super.createInfo(prePaySchVo.getCreator());
			prePaySchDomain.setSysInfo(info);
			prePaySchVo.setSysDate(info.getSysDate());
		}else{
			prePaySchDomain = this.prePaySchDao.findById(prePaySchVo.getPrePaySchId());
			info = prePaySchDomain.getSysInfo();
			super.modifyInfo(info, prePaySchVo.getModifier());
			prePaySchVo.setModifyDate(info.getModifyDate());
		}

		return prePaySchDomain;
	}
}
